/*
 * @(#)ExceptionHandler.java        0.1 14-Feb-2009
 *
 * Copyright 2008 Thomas Ford. All rights reserved.
 */
package edu.napier.soc.xfdm.exceptions;

import edu.napier.soc.xfdm.launcher.ApplicationInfo;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.swing.*;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Properties;

/**
 * @author Thomas Ford
 * @version 0.1, 14-Feb-2009
 */
public class ExceptionHandler implements Thread.UncaughtExceptionHandler {

	private static final String[] OPTIONS = {"Ignore", "Close Application",
			"Send Bug Report"};
	private static final int CONTINUE = 0;
	private static final int CLOSE = 1;
	private static final int SEND = 2;

	public void uncaughtException(Thread t, Throwable e) {
		showMessage(t, e);
	}

	private void showMessage(Thread t, Throwable e) {
		String msg = String.format("Unexpected problem on thread %s: %s",
				t.getName(), e.getMessage());
		StringWriter s1 = new StringWriter();
		PrintWriter p1 = new PrintWriter(s1);
		e.printStackTrace(p1);
		s1.flush();
		p1.flush();
		ExceptionPanel dp = new ExceptionPanel(msg, s1.toString());
		int opt = JOptionPane.showOptionDialog(
				null, dp, "Uncaught Exception", JOptionPane.DEFAULT_OPTION,
				JOptionPane.ERROR_MESSAGE, null, OPTIONS, 0);

		switch (opt) {
			case CONTINUE:
				return;
			case CLOSE:
				System.exit(-1);
			case SEND:
				send(s1.toString());
				break;
		}
	}

	private void send(String mes) {
		DescribePanel dp = new DescribePanel();
		int opt = JOptionPane.showOptionDialog(
				null, dp, "Problem Description", JOptionPane.OK_CANCEL_OPTION,
				JOptionPane.QUESTION_MESSAGE, null, null, null);

		switch (opt) {
			case JOptionPane.CLOSED_OPTION:
			case JOptionPane.CANCEL_OPTION:
				return;
			case JOptionPane.OK_OPTION:
				boolean success = sendEmail(dp.getText() + "\n\n"
						+ ApplicationInfo.VERSION + "\n\n" + mes);
				String output = null;

				if (success) {
					output = "Email sent successfully.";
				} else {
					output = "Email failed to send, you may send\n" +
							"emails to thomas.ford@blueyonder.co.uk.";
				}
				JOptionPane.showMessageDialog(null, output);
		}
	}

	private boolean sendEmail(String mes) {
		Properties props = new Properties();
		props.put("mail.smtp.user", "xfdmbugs@gmail.com");
		props.put("mail.smtp.host", "smtp.gmail.com");
		props.put("mail.smtp.port", "465");
		props.put("mail.smtp.starttls.enable", "true");
		props.put("mail.smtp.auth", "true");
		props.put("mail.smtp.socketFactory.port", "465");
		props.put("mail.smtp.socketFactory.class",
				"javax.net.ssl.SSLSocketFactory");
		props.put("mail.smtp.socketFactory.fallback", "false");

		try {
			Authenticator auth = new SMTPAuthenticator();
			Session session = Session.getInstance(props, auth);

			MimeMessage msg = new MimeMessage(session);
			msg.setText(mes);
			msg.setSubject("XFDM Bug");
			msg.setFrom(new InternetAddress("XFDM_Bug_Reports"));
			msg.addRecipient(Message.RecipientType.TO,
					new InternetAddress("xfdmbugs@gmail.com"));
			Transport.send(msg);
			return true;
		} catch (Exception ex) {
			return false;
		}
	}

	private class SMTPAuthenticator extends javax.mail.Authenticator {

		@Override
		public PasswordAuthentication getPasswordAuthentication() {
			return new PasswordAuthentication(
					// probably shouldn't store password but what the hell,
					// go hogwild :P
					"xfdmbugs@gmail.com", "xfdmpassword");
		}
	}
}